/*
 * Copyright (c) 2018-present, 美团点评
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

import 'dart:core';
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';

class FlutterLogan {
  static const MethodChannel _channel = MethodChannel('flutter_logan');

  ///[maxFileLen] 文件默认存储大小 10M
  static Future<bool> init(
      String aseKey, String aesIv, {int maxFileLen = 1024 * 1024 * 10}) async {
    if(!_support) {
      return false;
    }
    final bool result = await _channel.invokeMethod('init',{'aesKey': aseKey, 'aesIv': aesIv, 'maxFileLen': maxFileLen});
    return result;
  }

  static void error(String msg) => _log(msg, 1, "error");
  static void warn(String msg) => _log(msg, 3, "warn");
  static void debug(String msg) => _log(msg, 2, "debug");

  @Deprecated('请使用error/warn/debug方法')
  static void log(String log, [int type = 1]) => _log(log, type, "log");

  static void _log(String log, int type, String tag) {
    if(kDebugMode) {
      print('[Logan]($tag):$log');
    }
    if(_support) {
      _channel.invokeMethod('log', {'type': type, 'log': log});
    } else {
      print('[Logan]flutter_logan not support ${Platform.operatingSystem}');
    }
  }

  static bool get _support => Platform.isAndroid || Platform.isIOS;

  ///获取日志文件目录
  static Future<String> getLoganDir() async {
    if(!_support) {
      return "";
    }
    final String result = await _channel.invokeMethod('getLoganDir');
    return result;
  }

  ///上传非当天的文件，上传完成后删除文件
  static void uploadAll(String serverUrl, String appId, String unionId, String deviceId, String appVersion) {
    if(!_support) {
      return;
    }
    final t = DateTime.now();
    final today = DateTime(t.year, t.month, t.day);
    int f = today.microsecondsSinceEpoch ~/ 1000;
    String fileName = "$f";
    debug("uploadAll: today filename $f");
    getLoganDir().then((value) {
      Directory dir = Directory(value);
      dir.listSync().forEach((element) {
        if (!element.path.endsWith(fileName)) { //不是当天的日志文件，则上传
          debug("uploadAll: upload ${element.path}");
          String name = element.path.split('/').last;
          upload(serverUrl, name, appId, unionId, deviceId, appVersion, true);
        } else {
          debug("uploadAll: not upload ${element.path}");
        }
      });
    });
  }

  ///上传所有文件，但不会删除文件
  static void uploadAll2(String serverUrl, String appId, String unionId, String deviceId, String appVersion) {
    if(!_support) {
      return;
    }
    getLoganDir().then((value) {
      Directory dir = Directory(value);
      dir.listSync().forEach((element) {
        String name = element.path.split('/').last;
        upload(serverUrl, name, appId, unionId, deviceId, appVersion, false);
      });
    });
  }

  ///[serverUrl] 上报文件服务端地址
  ///
  ///[date] 记录日志文件的时间，格式为 毫秒时间戳
  ///
  ///[appId] 标识app应用，不能为中文
  ///
  ///[unionId] 标识当前使用的用户
  ///
  ///[deviceId] 标识设备id
  ///
  /// [appVersion] app版本号
  ///
  /// [delete] 是否删除[date]那天的日志文件
  static void upload(
      String serverUrl, String date, String appId, String unionId, String deviceId, String appVersion, bool delete) async {
    if(!_support) {
      return;
    }
    _channel.invokeMethod('upload', {
      'date': date,
      'serverUrl': serverUrl,
      'appId': appId,
      'unionId': unionId,
      'deviceId': deviceId,
      'appVersion': appVersion,
      'delete': delete
    });
  }

  static Future<void> flush() async {
    if(!_support) {
      return;
    }
    await _channel.invokeMethod('flush');
  }

  static Future<void> cleanAllLogs() async {
    if(!_support) {
      return;
    }
    await _channel.invokeMethod('cleanAllLogs');
  }
}
